home *** CD-ROM | disk | FTP | other *** search
/ Fritz: All Fritz / All Fritz.zip / All Fritz / FILES / PROGBLER / MATHASM.LZH / PLOT.ASM < prev    next >
Assembly Source File  |  1985-11-04  |  15KB  |  508 lines

  1.     PAGE    255,132
  2. ;-------------------------------------------------------------
  3. ;
  4. ;   orline.asm
  5. ;   orpt.asm
  6. ;
  7. ;   written by Bruce A. Smith  7/24/84
  8. ;
  9. ;-------------------------------------------------------------
  10. ;
  11. ; The two procedures here plot a point or draw a line on the
  12. ; medium resolution screen of the IBM PCjr or IBM PC.  The
  13. ; line drawing routine uses self-modifying code.  They both
  14. ; are written to OR the color bits onto the screen.  The
  15. ; objective of writing these routines was to achieve as much
  16. ; speed performance as possible with the 8088 microprocessor
  17. ; used in these machines.  The line drawing routine is
  18. ; approximately three times faster than the one listed in the
  19. ; BLUEBOOK OF ASSEMBLY ROUTINES FOR THE IBM PC & XT by
  20. ; Christopher Morgan.  It is also three times faster than the
  21. ; line drawing routine used in the ROM BASIC on the PCjr.
  22. ; The point plotting routine is a little more difficult to
  23. ; compare because the overhead of the call and the computation
  24. ; for the next point become significant.  In performance tests
  25. ; it plotted points half again as fast as the routine in the
  26. ; previously mentioned book by Christopher Morgan and in
  27. ; spite of the overhead it performed four times faster than
  28. ; the ROM BIOS point plotting routines.  So this point plotting
  29. ; routine is probably about five times faster than the ROM BIOS.
  30. ;
  31. ;------------------------------------------------------------
  32. ; REFERENCES
  33. ;
  34. ; Foley, James d. and Andries Van Dam, Fundamentals of Interactive
  35. ;   Computer Graphics, Addison-Wesley, Reading, MA, 1982.
  36. ;
  37. ; Morgan, Christopher L., Bluebook of Assembly Routines for
  38. ;   the IBM PC & XT, The Waite Group, New York, NY, 1984.
  39. ;
  40. ;------------------------------------------------------------
  41. ;
  42. DGROUP    GROUP    DATA
  43. DATA    SEGMENT WORD PUBLIC 'DATA'
  44.     ASSUME    DS:DGROUP
  45.         PUBLIC    COLOR,X1,X2,Y1,Y2
  46. ;
  47. ; the order and type of declaration is important here
  48. ;
  49. y2    dw    0
  50. x2    dw    0
  51. y1    dw    0
  52. x1    dw    0
  53. color    db    0
  54. ;
  55. ; color = color * 4 + 1, color 0 == mask
  56. ;
  57. ctableh    db    03Fh,0CFh,0F3h,0FCh
  58.     db    040h,010h,004h,001h
  59.     db    080h,020h,008h,002h
  60.     db    0C0h,030h,00Ch,003h
  61. ;
  62. fakedw    = 1000h
  63. ;
  64. DATA    ENDS
  65. ;
  66. ;------------------------------------------------------------
  67. ;
  68. PGROUP    GROUP    PROG
  69. PROG    SEGMENT    BYTE PUBLIC 'PROG'
  70.     PUBLIC    ORLINE,ORPT
  71.         ASSUME    CS:PGROUP
  72. ;
  73. ;-------------------------------------------------------------
  74. ;
  75. ;   orline.asm
  76. ;
  77. ;------------------------------------------------------------
  78. ;
  79. ; ROUTINE TO OR A LINE ONTO MEDIUM RESOLUTION SCREEN
  80. ;
  81. ; uses Bresenham's algorithm
  82. ;
  83. orline    proc    near
  84.     push    bp        ; save calling bp
  85.                     ; only reg needed to save for 'C'
  86.         push    ds        ; save ds
  87. ; ------------------------------
  88. ; get x & y values
  89.     mov    si,OFFSET y2    ; addr y2
  90.         lodsw            ; ax = y2
  91.         xchg    ax,dx        ; dx = y2
  92.         lodsw            ; ax = x2
  93.         xchg    ax,di        ; di = x2
  94.         lodsw            ; ax = y1
  95.         xchg    ax,cx        ; cx = y1
  96.         lodsw            ; ax = x1
  97.         mov    bx,si        ; bx = addr color
  98.         xchg    ax,si        ; si = x1
  99. ;
  100.     cmp    si,di        ; cmp x1,x2
  101.         jle    swapxy        ; skip if (x1<=x2)
  102.         xchg    cx,dx        ; (x1>x2): swap y1,y2
  103.         xchg    si,di        ; swap x1,x2
  104. swapxy:
  105. ;
  106. ;    ............................................
  107. ;    |         H        |       L        |
  108. ; -----------------------------------------------
  109. ; ax |            |            |
  110. ; -----------------------------------------------
  111. ; bx |            addr color            |
  112. ; -----------------------------------------------
  113. ; cx |        0    |    y1        |  if ( x1 > x2 )
  114. ; -----------------------------------------------  swap (x1,y1) with
  115. ; dx |        0    |    y2        |       (x2,y2)
  116. ; -----------------------------------------------  ie.
  117. ; si |            x1            |    xchg cx,dx
  118. ; -----------------------------------------------    xchg si,di
  119. ; di |            x2            |
  120. ; -----------------------------------------------
  121. ; bp |                        |
  122. ; ----------------------------------,=-----------
  123. ;
  124. ;
  125. ; ch = deldy = (y1>y2) ? -80 : 80
  126. ; dx = |y2-y1|
  127.         sub    dx,cx        ; y2-y1
  128.     mov    al,80        ; deldy = 80
  129.         jge    ydown        ; skip if (y1<=y2)
  130.         neg    dx        ; |y2-y1|
  131.         neg    al        ; deldy = -1
  132. ydown:
  133.     sub    di,si        ; x2-x1
  134. ; di = |x2-x1|
  135. ;
  136. ;    ............................................
  137. ;    |         H        |       L        |
  138. ; -----------------------------------------------   al=80
  139. ; ax |            |   (y1>y2)? -80: 80    |   dx-cx = y2-y1
  140. ; -----------------------------------------------   if neg (y1>y2)
  141. ; bx |            addr color            |     neg dx =|y2-y1|
  142. ; -----------------------------------------------     al=-80
  143. ; cx |        0    |    y1        |
  144. ; -----------------------------------------------   deldy = al
  145. ; dx |        0    |    absdy = |y2-y1|    |
  146. ; -----------------------------------------------
  147. ; si |            x1            |
  148. ; -----------------------------------------------   di-si
  149. ; di |        absdx =    x2-x1            |   = |x2-x1|
  150. ; -----------------------------------------------
  151. ; bp |                        |
  152. ; -----------------------------------------------
  153. ;
  154. ;
  155.     cmp    di,dx        ; absdx,absdy
  156.         lahf
  157.         jnl    minmax        ; skip if (absdx>=absdy)
  158.         xchg    di,dx
  159. minmax:
  160. ; dx = dmin
  161. ; di = dmax
  162. ;
  163. ;    ............................................
  164. ;    |         H        |       L        |  if (absdx < absdy)
  165. ; -----------------------------------------------  cmp di,dx  lahf
  166. ; ax | flags absdx,absdy|    deldy        |  jnl -
  167. ; -----------------------------------------------    swap(absdx,absdy)
  168. ; bx |            addr color            |    xchg di,dx
  169. ; -----------------------------------------------  -:
  170. ; cx |        0    |    y1        |
  171. ; -----------------------------------------------
  172. ; dx |        0    |    dmin        |
  173. ; -----------------------------------------------
  174. ; si |            x1            |
  175. ; -----------------------------------------------
  176. ; di |            dmax            |
  177. ; -----------------------------------------------
  178. ; bp |                        |
  179. ; -----------------------------------------------
  180. ;
  181. ;
  182.     xchg    ax,bp        ; bp=flags(absdx,absdy) & deldy
  183. ;
  184. ; ROUTINE TO FIND INITIAL Y-ADDR, X-ADDR, AND ROTATED COLOR
  185. ;
  186. ; multiply y-coord by bytes per row and adjust for even/odd lines
  187.     ror    cl,1        ; adjust odd/even
  188.         mov    ax,cx        ; ax = cx = adj y-coord
  189.         and    al,7Fh        ; page mask
  190.         sal    cx,1        ; times 2
  191.         sal    cx,1        ; times 4
  192.         add    cx,ax        ; y-coord times 5
  193.         sal    cx,1        ; times 10
  194.         sal    cx,1        ; times 20
  195.         sal    cx,1        ; times 40
  196.         sal    cx,1        ; times 80
  197. ;
  198. ;    ............................................
  199. ;    |         H        |       L        |
  200. ; -----------------------------------------------
  201. ; ax |        0    |            |
  202. ; -----------------------------------------------
  203. ; bx |         addr color = addr ctableh-1    |
  204. ; -----------------------------------------------
  205. ; cx |            y-addr            |
  206. ; -----------------------------------------------
  207. ; dx |        0    |    dmin        |
  208. ; -----------------------------------------------
  209. ; si |            x1            |
  210. ; -----------------------------------------------
  211. ; di |            dmax            |
  212. ; -----------------------------------------------
  213. ; bp | flags absdx,absdy|    deldy        |
  214. ; -----------------------------------------------
  215. ;
  216. ;
  217. ; compute the rotated mask and color
  218. ; bx = ctableh-1 = addr color
  219.     mov    al,3        ; pixel position mask
  220.     and    ax,si        ; just the bit count into the index
  221.     add    al,[bx]        ; pixel position + color (* 4 + 1)
  222.     xlat            ; look up the masks al=[al+bx]
  223. ;
  224.     mov    bx,0B800H    ; disp seg base addr
  225.         mov    ds,bx        ; ds = display base addr
  226. ;
  227. ;  al = rotated color
  228. ;  cx = y-addr offset
  229. ;  ds = display addr
  230. ;
  231. ;    ............................................
  232. ;    |         H        |       L        |
  233. ; -----------------------------------------------
  234. ; ax |        0    |    rotated color    |
  235. ; -----------------------------------------------
  236. ; bx |            |            |
  237. ; -----------------------------------------------
  238. ; cx |            y-addr            |
  239. ; -----------------------------------------------
  240. ; dx |        0    |    dmin        |
  241. ; -----------------------------------------------
  242. ; si |            x1            |
  243. ; -----------------------------------------------
  244. ; di |            dmax            |
  245. ; -----------------------------------------------
  246. ; bp | flags absdx,absdy|    deldy        |
  247. ; -----------------------------------------------
  248. ;
  249. ;
  250.     sal    dx,1        ; dx = delse = dmin * 2
  251.         xchg    cx,di        ; cx = dmax, di = y-addr
  252.         xchg    ax,dx        ; ax=delse, dx=rotated color
  253.         xchg    ax,bp        ; ax=flags(absdx,absdy), bp=delse
  254. ;
  255. ;    ............................................
  256. ;    |         H        |       L        |
  257. ; -----------------------------------------------
  258. ; ax | flags absdx,absdy|    deldy        |
  259. ; -----------------------------------------------
  260. ; bx |            |            |
  261. ; -----------------------------------------------
  262. ; cx |            dmax            |
  263. ; -----------------------------------------------
  264. ; dx |        0    |    rotated color    |
  265. ; -----------------------------------------------
  266. ; si |            x1            |
  267. ; -----------------------------------------------
  268. ; di |            y-addr            |
  269. ; -----------------------------------------------
  270. ; bp |          dmin * 2 = delse        |
  271. ; -----------------------------------------------
  272. ;
  273. ;
  274.     sahf            ; cmp absdx,absdy
  275.         pushf
  276. ;
  277.     cbw            ; ax = deldy
  278.     mov    cs:delsy,ax    ; save deldy
  279.     mov    cs:deldy,ax
  280.     mov    cs:deldy2,ax
  281.         mov    bx,di        ; bx = y-addr
  282.         or    ax,ax
  283.         js    negdeldy    ; if deldy<0 jmp
  284. ;
  285.         test    bh,20H        ; is page bit set?
  286.         jz    toggle        ; skip to toggle page
  287. ;
  288.         add    bx,ax        ; add deldy to y-addr
  289.         jmp    toggle        ; skip to toggle page
  290. negdeldy:
  291.         test    bh,20H        ; is page bit set?
  292.         jnz    toggle        ; skip to toggle page
  293. ;
  294.         add    bx,ax        ; add deldy to y-addr
  295. toggle:
  296.     xor    bh,20H        ; flip page bit
  297. ; bx = next y-addr
  298. ;
  299. ;    ............................................
  300. ;    |         H        |       L        |
  301. ; -----------------------------------------------
  302. ; ax |            |            |
  303. ; -----------------------------------------------
  304. ; bx |            y-addr (next)        |
  305. ; -----------------------------------------------
  306. ; cx |            dmax            |
  307. ; -----------------------------------------------
  308. ; dx |        0    |    rotated color    |
  309. ; -----------------------------------------------
  310. ; si |            x1            |
  311. ; -----------------------------------------------
  312. ; di |            y-addr            |
  313. ; -----------------------------------------------
  314. ; bp |          dmin * 2 = delse        |
  315. ; -----------------------------------------------
  316. ;
  317. ;
  318.     xchg    ax,bp        ; ax = dmin * 2 = delse
  319.         mov    cs:delse,ax    ; save delse
  320.         mov    cs:delse2,ax    ; save delse
  321.         sub    ax,cx        ; ax = dmin * 2 - dmax = d
  322.         mov    bp,ax        ; bp = d = error term
  323.         sub    ax,cx        ; ax = dmin * 2 - dmax * 2
  324.         mov    cs:delde,ax    ; save delde
  325.         mov    cs:delde2,ax    ; save delde
  326. ;
  327.     xchg    ax,bx        ; ax = next y-addr
  328. ;
  329. ; figure x-coord address
  330.     mov    bx,si        ; get x-coordinate
  331.         sar    bx,1        ; divide
  332.     sar    bx,1        ; by 4
  333. ;  bx = x-addr offset
  334. ;
  335. ;    ............................................
  336. ;    |         H        |       L        |
  337. ; -----------------------------------------------
  338. ; ax |            y-addr    (next)         |
  339. ; -----------------------------------------------
  340. ; bx |            x-addr            |
  341. ; -----------------------------------------------
  342. ; cx |            loop count        |
  343. ; -----------------------------------------------
  344. ; dx |            |    rotated color    |
  345. ; -----------------------------------------------
  346. ; si |            x value            |
  347. ; -----------------------------------------------
  348. ; di |            y-addr            |
  349. ; -----------------------------------------------
  350. ; bp |            error term        |
  351. ; -----------------------------------------------
  352. ;
  353. ;
  354.     popf            ; cmp absdx,absdy
  355.     jns    delsx2        ; if (absdx>=absdy) goto delsx2
  356. ;
  357. ; -----------------------------------------------
  358. ; delsx = 0  (absdx < absdy)
  359. ;
  360.     or    [bx][di],dl    ; or disp with color (plot point)
  361.         jcxz    lineexit    ; quit when cx=0
  362.     or    bp,bp        ; set bp flags
  363.         jge    diagonal    ; if bp>=0 jmp
  364. ;
  365. ; case for straight move
  366. straight:
  367.         xchg    ax,di        ; every other for page adj
  368. delsy    = $+1
  369.         add    ax,fakedw    ; ++y
  370. ;
  371.     or    [bx][di],dl    ; or disp with color (plot point)
  372.         dec    cx        ; --loop counter
  373.         jz    lineexit    ; quit when cx=0
  374. ;
  375. delse    = $+2
  376.     add    bp,fakedw    ; update error term
  377.         js    straight    ; if bp<0 goto straight
  378. ;
  379. ; case for diagonal move
  380. diagonal:
  381.         inc    si        ; ++x value
  382.         mov    bx,si        ; bx = x value
  383.         sar    bx,1
  384.         sar    bx,1        ; bx = x addr offset
  385. ;
  386.         ror    dl,1        ; adjust color position
  387.         ror    dl,1
  388. ;
  389.         xchg    ax,di        ; every other for page adj
  390. deldy    = $+1
  391.         add    ax,fakedw    ; ++y
  392. ;
  393.     or    [bx][di],dl    ; or disp with color (plot point)
  394.         dec    cx        ; --loop counter
  395.         jz    lineexit    ; quit when cx=0
  396. ;
  397. delde    = $+2
  398.     add    bp,fakedw    ; update error term
  399.         js    straight    ; if bp<0 goto straight
  400.         jmp    diagonal    ; if bp>=0 goto diagonal
  401. ;
  402. ; -----------------------------------------------
  403. delsx2:
  404. ; delsx = 1  (absdx >= absdy)
  405. ;
  406.     or    [bx][di],dl    ; or disp with color (plot point)
  407.         jcxz    lineexit    ; quit when cx=0
  408.     or    bp,bp        ; set bp flags
  409.         jge    diagonal2    ; if bp>=0 jmp
  410. ;
  411. ; case for straight move
  412. straight2:
  413.         inc    si        ; ++x value
  414.         mov    bx,si        ; bx = x value
  415.         sar    bx,1
  416.         sar    bx,1        ; bx = x addr offset
  417. ;
  418.         ror    dl,1        ; adjust color position
  419.         ror    dl,1
  420. ;
  421.     or    [bx][di],dl    ; or disp with color (plot point)
  422.         dec    cx        ; --loop counter
  423.         jz    lineexit    ; quit when cx=0
  424. ;
  425. delse2    = $+2
  426.     add    bp,fakedw    ; update error term
  427.         js    straight2    ; if bp<0 goto straight
  428. ;
  429. ; case for diagonal move
  430. diagonal2:
  431.         inc    si        ; ++x value
  432.         mov    bx,si        ; bx = x value
  433.         sar    bx,1
  434.         sar    bx,1        ; bx = x addr offset
  435. ;
  436.         ror    dl,1        ; adjust color position
  437.         ror    dl,1
  438. ;
  439.         xchg    ax,di        ; every other for page adj
  440. deldy2    = $+1
  441.         add    ax,fakedw    ; ++y
  442. ;
  443.     or    [bx][di],dl    ; or disp with color (plot point)
  444.         dec    cx        ; --loop counter
  445.         jz    lineexit    ; quit when cx=0
  446. ;
  447. delde2    = $+2
  448.     add    bp,fakedw    ; update error term
  449.         js    straight2    ; if bp<0 goto straight
  450.         jmp    diagonal2    ; if bp>=0 goto diagonal
  451. ;
  452. ; -----------------------------------------------
  453. lineexit:
  454.     pop    ds        ; restore ds
  455.     pop    bp        ; restore calling bp
  456.         ret
  457. ;
  458. orline    endp
  459. ;
  460. ;------------------------------------------------------------
  461. ;
  462. ;   orx<.asm
  463. ;
  464. ;------------------------------------------------------------
  465. ;
  466. ; ROUTINE TO OR A POINT ONTO MEDIUM RES COLOR SCREEN
  467. ;
  468. orpt    proc    near
  469. ;
  470. ; get initial values for x and y
  471.         mov    si,OFFSET y1    ; addr y1
  472.         lodsw            ; ax = y1
  473. ;
  474. ; multiply y-coord by bytes per row and adjust for even/odd lines
  475.     ror    al,1        ; adjust odd/even
  476. ;
  477.         mov    dx,0B87FH    ; disp addr and page mask
  478.     and    dl,al        ; mask page bit, disp + y.coord
  479.         sal    ax,1        ; times 32
  480.         sal    ax,1        ; times 64
  481.         add    dx,ax        ; addr disp seg + y-coord times 5 (80)
  482. ;
  483. ; compute x-coord address offset
  484.         lodsw            ; ax = x1
  485.     mov    di,ax        ; get x-coordinate
  486.         sar    di,1        ; divide
  487.     sar    di,1        ; by 4
  488. ;
  489. ; compute the rotated mask and color
  490.     and    al,3        ; just the bit count into the index
  491.     add    al,[si]        ; pixel position + color (* 4 + 1)
  492.         mov    bx,si        ; bx = ctableh - 1
  493.     mov    si,ds        ; save ds
  494.     xlat            ; look up the masks al=[al+bx]
  495. ;
  496.         mov    ds,dx        ; set seg to disp + y-addr
  497.      or    [di],al        ; or the byte with the color
  498. ;
  499.     mov    ds,si        ; restore ds
  500.         ret
  501. ;
  502. orpt    endp
  503. ;
  504. ;------------------------------------------------------------
  505. ;
  506. PROG    ENDS
  507.     END
  508.